<template>
    <!-- #ifdef H5 || APP-PLUS -->
    <view :class="['zb-table','zb-table-fixed-header',!border && (bodyTableLeft>50 || headerTableLeft>50) && 'scroll-left-fixed']">
        <view class="zb-table-content" style="flex :  1">
            <view class="zb-table-scroll" style="height: 100%;">
                <template v-if="showHeader">
                    <view class="zb-table-header top-header-uni">
                        <scroll-view class="zb-table-headers" @scroll="handleTableScrollLeft" scroll-x="true" scroll-y="false" id="tableHeaders"
                            scroll-anchoring="true" :scroll-left="headerTableLeft" style="
						height: 100%">

                            <view class="zb-table-fixed">
                                <view class="zb-table-thead" style="position: relative;">
                                    <view class="item-tr">
                                        <view @click.stop="sortAction(item,index)" class="item-th" :style="[{
                                            width : `${item.width ? item.width : '100'}px`,
                                            flex : index===transColumns.length-1 ? 1 : 'none',
                                            minWidth : `${item.width ? item.width : '100'}px`,
                                            borderRight : `${border ? '1px solid #e8e8e8' : ''}`,
                                            borderTop : `${border ? '1px solid #e8e8e8' : ''}`,
                                            textAlign : item.align || 'left' }, 
                                        getHeaderCellStyle(item,index)]"
                                            v-for="(item,index) in transColumns" :key="index">
                                            <template v-if="item.type==='selection'">
                                                <view class="checkbox-item">
                                                    <tableCheckbox :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
                                                </view>
                                            </template>
                                            <template v-else>
                                                {{ item.label }}
                                                <view class="sorter-table" v-if="item.sorter">
                                                    <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]">
                                                    </view>
                                                    <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]">
                                                    </view>
                                                </view>
                                            </template>

                                        </view>
                                        <view v-if="scrollbarSize" class="item-th " :style="{
                                borderTop:`${border ? '1px solid #e8e8e8' : ''}`,
                                padding:0,
                                width:`${scrollbarSize}px`,
                              }">
                                        </view>
                                    </view>
                                </view>
                            </view>
                        </scroll-view>
                    </view>
                </template>
                <template v-if="!data.length">
                    <view class="no-data">暂无数据~~</view>
                </template>
                <scroll-view class="zb-table-body" ref="tableBody" scroll-x="true" scroll-y="true" id="tableBody" :lower-threshold="40"
                    :upper-threshold="10" @scrolltolower="scrolltolower" @scrolltoupper="(e)=>debounce(scrollToLeft)(e)" @scroll="handleBodyScroll"
                    :scroll-left="bodyTableLeft" :scroll-top="bodyScrollTop" :style=" `height: calc(100% - ${showSummary?80:40}px)`">
                    <view class="zb-table-fixed">
                        <view class="zb-table-tbody">
                            <view :class="['item-tr',highlight&&isHighlight(item,index)?'current-row' : '']" @click.stop="rowClick(item,index)" v-for="(item,index) in transData"
                                :key="item.key">
                                <view :style="[{
							        width:`${ite.width ? ite.width : '100'}px`,
										  flex:i===transColumns.length-1?1 : 'none',
										  minWidth:`${ite.width?ite.width : '100'}px`,
										  borderRight:`${border?'1px solid #e8e8e8' : ''}`,
											textAlign:ite.align || 'left',
									  },cellStyle&&getCellStyle(item,ite,index,i)]"
                                    @click="cellClick(item,index,ite)" :class="['item-td',stripe ? (index % 2) != 0 ? 'odd' : 'even' : '']" v-for="(ite,i) in transColumns"
                                    :key="i">
                                    <template v-if="ite.type==='operation'">
                                        <view style="display: flex;align-items: center;height: 100%">
                                            <view v-for="ren,ind in permission(item,ite.renders,index)" :key="ind" @click.stop="$emit(ren.func,item,index)"
                                                :style="{
	                          display:'flex',
	                          alignItems: 'center',
	                          marginRight:ite.renders.length>1?'8px' : '0'
	                        }">
                                                <template v-if="ren.type==='custom'">
                                                    <view :class="ren.class || ''" style="cursor: pointer">
                                                        {{ren.name}}
                                                    </view>
                                                </template>
                                                <template v-else>
                                                    <button :class="ren.class || ''" :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
                                                </template>
                                            </view>
                                        </view>
                                    </template>
                                    <template v-else-if="ite.type==='selection'">
                                        <view class="checkbox-item">
                                            <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked" />
                                        </view>
                                    </template>
                                    <template v-else-if="ite.type==='index'">
                                        {{index+1}}
                                    </template>
                                    <template v-else-if="ite.type==='img'">
                                        <view class="checkbox-item">
                                            <template v-if="item[ite.name]">
                                                <image @click.stop="previewImage(item,item[ite.name],iImage)" v-for="iImageTem,iImage in imgs(item[ite.name])"
                                                    :show-menu-by-longpress="false" :key="iImage" :src="iImageTem" style="width: 40px;height:30px; "
                                                    mode="aspectFit"></image>
                                            </template>
                                            <text v-else>{{ite.emptyString}}</text>
                                        </view>
                                    </template>
                                    <template v-else>
                                        <!--                      {{ ite.filters?itemFilter(item,ite):(item[ite.name]==null||item[ite.name]==='')?ite.emptyString:item[ite.name] }}-->
                                        {{ ite.filters?itemFilter(item,ite):formatterAction(item,ite,index,i) }}
                                    </template>
                                </view>
                            </view>
                        </view>
                    </view>
                </scroll-view>
                <table-h5-summary :scrollbarSize="scrollbarSize" :data="data" :handleFooterTableScrollLeft="handleFooterTableScrollLeft"
                    :headerFooterTableLeft="headerFooterTableLeft" v-if="showSummary" :showSummary="showSummary" :transColumns="transColumns" :border="border"
                    :summary-method="summaryMethod" :sumText="sumText" :fixedLeftColumns="fixedLeftColumns" />
            </view>
            <view class="zb-table-fixed-left" v-if="isFixedLeft" :style=" {height:  `calc(100% - ${scrollbarSize}px)`}">
                <template v-if="showHeader">
                    <view class="zb-table-header" style="display: flex">
                        <view class="item-tr" style="" @click.stop="rowClick(item,index)" v-for="(item,index) in fixedLeftColumns" :key="index">
                            <view :style="{
	               width:`${item.width?item.width : '100'}px`,
	               borderRight:`${border?'1px solid #e8e8e8' : ''}`,
	               borderTop:`${border?'1px solid #e8e8e8' : ''}`,
                textAlign:item.align || 'left'
	            }"
                                @click.stop="sortAction(item,index)" class="item-th">
                                <template v-if="item.type==='selection'">
                                    <view class="checkbox-item">
                                        <tableCheckbox :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
                                    </view>
                                </template>
                                <template v-else>
                                    {{ item.label }}
                                    <view class="sorter-table" v-if="item.sorter">
                                        <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]">
                                        </view>
                                        <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]">
                                        </view>
                                    </view>
                                </template>
                            </view>
                        </view>

                    </view>
                </template>
                <scroll-view scroll-y="true" id="leftTableFixed" :upper-threshold="15" @scrolltoupper="(e)=>scrollToFixedLeft(e)" @scroll="leftFixedScrollAction"
                    :scroll-top="leftFiexScrollTop" class="zb-table-body-inner" :style=" `height : calc(100% - ${showSummary ? 80 : 40}px)`">
                    <view class="zb-table-fixed">
                        <view class="zb-table-tbody">
                            <view :class="['item-tr',stripe ? (i % 2) != 0? 'odd' : 'even':'',highlight&&isHighlight(ite,i)?'current-row' : '']"
                                v-for="(ite,i) in transData" @click.stop="rowClick(ite,i)" :key="ite.key" style="">
                                <view class='item-td' @click="cellClick(ite,index,item)" :style="[{
	                       width:`${item.width?item.width : '100'}px`,
	                       borderRight:`${border?'1px solid #e8e8e8' : ''}`,
	                       textAlign:item.align || 'left'
	                      },cellStyle&&getCellStyle(ite,item,i,index)]"
                                    :key="index" v-for="(item,index) in fixedLeftColumns">
                                    <template v-if="item.type==='selection'">
                                        <view class="checkbox-item">
                                            <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,ite)" :cellData="ite" :checked="ite.checked" />
                                        </view>
                                    </template>
                                    <template v-else-if="item.type==='index'">
                                        {{i+1}}
                                    </template>
                                    <template v-else>
                                        {{ite[item.name]||item.emptyString}}
                                    </template>
                                </view>
                            </view>
                        </view>
                    </view>
                </scroll-view>
                <table-side-summary :scrollbarSize="scrollbarSize" v-if="showSummary&&!(scrollbarSize>0)" :data="data" :showSummary="showSummary"
                    :transColumns="transColumns" :border="border" :summary-method="summaryMethod" :sumText="sumText" :fixedLeftColumns="fixedLeftColumns" />
            </view>
        </view>
        <zb-load-more v-if="isLoadMore&&!completeLoading" />
    </view>
    <!-- #endif -->
    <!-- #ifndef H5 || APP-PLUS -->
    <view class="zb-table-applet">
        <view class="zb-table-content" style="white-space: nowrap">
            <scroll-view <!-- #ifdef MP-ALIPAY -->
                @scroll="scrollAlipay"
                <!-- #endif  -->

                @scrolltolower="scrolltolower"
                <!-- #ifdef MP-ALIPAY -->
                style=" height: 100%;overflow-x:scroll"
                <!-- #endif  -->
                <!-- #ifndef MP-ALIPAY -->
                style=" height: 100%"
                <!-- #endif  -->
                scroll-y="true"
                scroll-x="true">
                <view class="zb-table-scroll">
                    <template v-if="showHeader">
                        <view class="zb-table-header top-header-uni" style="">
                            <view class="zb-table-fixed">
                                <view class="zb-table-thead" style="position: relative;">
                                    <view class="item-tr">
                                        <view @click.stop="sortAction(item,index)" :class="['item-th',index <fixedLeftColumns.length&&'zb-stick-side']"
                                            :style="{
	                              left:`${item.left}px`,
	                              width:`${item.width?item.width:'100'}px`,
															  flex:index===transColumns.length-1?1:'none',
															  minWidth:`${item.width?item.width:'100'}px`,
															   borderRight:`${border?'1px solid #e8e8e8':''}`,
															  borderTop:`${border?'1px solid #e8e8e8':''}`,
															   textAlign:item.align||'left'
														  }"
                                            v-for="(item,index) in transColumns" :key="index">
                                            <template v-if="item.type==='selection'">
                                                <view class="checkbox-item" v-if="!isSingle">
                                                    <tableCheckbox :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
                                                </view>
                                            </template>
                                            <template v-else>
                                                {{ item.label||'' }}
                                                <view class="sorter-table" v-if="item.sorter">
                                                    <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]">
                                                    </view>
                                                    <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]">
                                                    </view>
                                                </view>
                                            </template>
                                        </view>
                                    </view>
                                </view>
                            </view>
                        </view>
                    </template>
                    <template v-if="!data.length">
                        <view class="no-data">暂无数据~~</view>
                    </template>
                    <view class="zb-table-fixed">
                        <view class="zb-table-tbody">
                            <view :class="['item-tr',highlight&&isHighlight(item,index)?'current-row':'']" @click.stop="rowClick(item,index)" v-for="(item,index) in transData"
                                :key="item.key">
                                <view :style="[{
                      left:`${ite.left}px`,
                      width:`${ite.width?ite.width:'100'}px`,
                      flex:i===transColumns.length-1?1:'none',
                      minWidth:`${ite.width?ite.width:'100'}px`,
                      borderRight:`${border?'1px solid #e8e8e8':''}`,
                      textAlign:ite.align||'left',
                    },getCellStyle(item,ite,index,i)]"
                                    @click="cellClick(item,index,ite)" :class="['item-td', i <fixedLeftColumns.length&&'zb-stick-side',stripe?(index % 2) != 0?'odd':'even':'']"
                                    v-for="(ite,i) in transColumns" :key="i">
                                    <template v-if="ite.type==='operation'">
                                        <view style="display: flex;align-items: center;height: 100%">
                                            <view v-for="ren,ind in permission(item,ite.renders,index)" :key="ind" @click.stop="$emit(ren.func,item,index)"
                                                :style="{
	                          display : 'flex',
	                          alignItems: 'center',
	                          marginRight:ite.renders.length>1?'8px' : '0'
	                        }">
                                                <template v-if="ren.type==='custom'">
                                                    <view :class="ren.class || '' " style="cursor: pointer">
                                                        {{ren.name}}
                                                    </view>
                                                </template>
                                                <template v-else>
                                                    <button :class=" ren.class ||'' " :type="ren.type||'primary'" :size="ren.size || 'mini'">{{ren.name}}</button>
                                                </template>
                                            </view>
                                        </view>
                                    </template>
                                    <template v-else-if="ite.type==='selection'">
                                        <view class="checkbox-item">
                                            <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked" />
                                        </view>
                                    </template>
                                    <template v-else-if="ite.type==='img'">
                                        <template v-if="item[ite.name]">
                                            <view class="checkbox-item" @click.stop>
                                                <image @click.stop="previewImage(iImageTem,item[ite.name],iImage)" v-for="iImageTem,iImage in imgs(item[ite.name])"
                                                    :show-menu-by-longpress="false" :key="iImage" :src="iImageTem" style="width: 40px;height:30px; "
                                                    mode="aspectFit"></image>
                                            </view>
                                        </template>

                                        <text v-else>{{ite.emptyString}}</text>
                                    </template>
                                    <template v-else-if="ite.type==='index'">
                                        {{index+1}}
                                    </template>
                                    <template v-else>
                                        <!--                    {{ ite.filters?itemFilter(item,ite):(item[ite.name]==null||item[ite.name]==='')?ite.emptyString:item[ite.name] }}-->
                                        {{ ite.filters?itemFilter(item,ite):formatterAction(item,ite,index,i) }}
                                    </template>
                                </view>
                            </view>
                        </view>
                    </view>
                    <table-summary v-if="showSummary" :data="data" :showSummary="showSummary" :fixedLeftColumns="fixedLeftColumns" :transColumns="transColumns"
                        :border="border" :summary-method="summaryMethod" :sumText="sumText" />
                </view>
            </scroll-view>
        </view>
        <zb-load-more v-if="isLoadMore&&!completeLoading" />
    </view>
    <!-- #endif -->
</template>
<script>
import TableCheckbox from './components/table-checkbox.vue'
import TableSummary from "./components/table-summary.vue";
import TableSideSummary from "./components/table-side-summary.vue";
import TableH5Summary from './components/table-h5-summary'
import ZbLoadMore from './components/zb-load-more'

// #ifdef H5
import {
    getScrollbarSize
} from "./js/util";
// #endif

export default {
    components: {
        TableCheckbox,
        TableSummary,
        TableSideSummary,
        TableH5Summary,
        ZbLoadMore
    },
    props: {
        highlight: {
            type: Boolean,
            default: false
        },
        itemDate: {
            type: Object,
            default: () => { }
        },
        columns: {
            type: Array,
            default: () => []
        },
        showSummary: {
            type: Boolean,
            default: false
        },
        isShowLoadMore: {
            type: Boolean,
            default: false
        },
        data: {
            type: Array,
            default: () => []
        },
        sumText: {
            type: String,
            default: '合计'
        },
        showHeader: {
            type: Boolean,
            default: true
        },
        border: {
            type: Boolean,
            default: false
        },
        stripe: {
            type: Boolean,
            default: true
        },
        fit: {
            type: Boolean,
            default: false
        },
        isSingle: {
            type: Boolean,
            default: false
        },
        rowKey: [String, Function],
        summaryMethod: Function,
        pullUpLoading: Function,
        formatter: Function,
        cellStyle: Function,
        cellHeaderStyle: Function,
        permissionBtn: Function,
    },
    computed: {
        loadMoreHeight() {
            return this.isLoadMore ? 40 : 0
        },
        fixedLeftColumns() {
            let arr = []
            for (let i = 0; i < this.columns.length; i++) {
                let item = this.columns[i]
                if (item.fixed) {
                    arr.push(item)
                } else {
                    break
                }
            }
            return arr
        },
        imgs() {
            return (item) => {
                return typeof item === 'string' ? [item] : item
            }
        },
        itemfilters() {
            return (item, ite) => {
                if (item[ite.name] == null) {
                    return ite.emptyString
                }
                return item[ite.name]
            }
        },
        scrollbarSize() {
            // #ifdef H5
            return getScrollbarSize()
            // #endif

            // #ifndef H5
            return 0
            // #endif
        },
        isFixedLeft() {
            if (!this.columns.length) {
                return false
            }
            if (!this.data.length) {
                return false
            }
            let [firstArr] = this.columns
            return !!firstArr.fixed;
        },
        transColumns() {
            if (this.fit) {
                this.columns.forEach(column => {
                    if (column.type === "operation" && column.renders) {
                        let str = ''
                        column.renders.map((item) => {
                            str += item.name
                        })
                        column.width = this.getTextWidth(str) + column.renders.length * 40
                    } else if (column.type === "img") {

                    } else if (column.type === "selection") { } else {
                        let arr = [this.getTextWidth(column.label)]
                        this.data.forEach(data => {
                            let str = (data[column.name] + '')
                            if (str === 'undefined') {
                                arr.push(30)
                            } else {
                                let width = this.getTextWidth(str)
                                arr.push(width)
                            }
                        })
                        column.width = Math.max(...arr) + 20
                    }
                })
            }
            let number = 0
            this.columns.forEach((item, index) => {
                if (item.type === "operation" && item.renders && !item.width) {
                    let str = ''
                    item.renders.map((item) => {
                        str += item.name
                    })
                    item.width = this.getTextWidth(str) + item.renders.length * 40
                }
                if (item.type === "img") {
                    if (!item.width) {
                        let arr = []
                        let widImg = this.getTextWidth(item.label)
                        this.data.forEach(data => {
                            if (data[item.name]) {
                                let urls = typeof data[item.name] === 'string' ? [data[item.name]] :
                                    data[item.name]
                                arr.push(urls.length)
                            }
                            item.width = Math.max(...arr) * 40 + widImg
                        })
                    }

                }
                if (item.fixed) {
                    if (index === 0) {
                        item.left = 0
                        number += item.width
                    } else {
                        item.left = number
                        number += item.width
                    }
                }
                item.emptyString = item.emptyString || ' '
            })
            return this.columns
        },
        transData() {
            let flag = this.columns.some(item => item.type === 'selection')
            this.data.forEach((item, index) => {
                if (flag) {
                    if (item.checked) {
                        if (!this.selectArr.length) {
                            this.selectArr.push(item)
                        }
                    }
                }
                if (this.rowKey) {
                    if (typeof this.rowKey === 'function') {
                        item.key = Object.freeze(this.rowKey(item)) || Date.now()
                    } else {
                        item.key = Object.freeze(item[this.rowKey]) || Date.now()
                    }
                } else {
                    item.key = index
                }
            })
            if (flag) {
                if (this.data.length) {
                    let le = this.data.filter(item => item.checked).length
                    if (le) {
                        if (le === this.data.length) {
                            this.checkedAll = true
                        } else {
                            this.indeterminate = true
                        }
                    } else {
                        this.checkedAll = false
                        this.indeterminate = false
                        this.selectArr = []
                    }
                } else {
                    this.checkedAll = false
                    this.indeterminate = false
                    this.selectArr = []
                }
            }
            return this.data
        },
        isHighlight() {
            return (item, index) => {
                if (this.rowKey) {
                    return item.key === this.currentRow['key']
                } else {
                    return index === this.currentRowIndex
                }
            }
        },
        getHeaderCellStyle() {
            return (column, columnIndex, childIndex) => {
                const cellStyle = this.cellHeaderStyle;
                if (typeof cellStyle === 'function') {
                    return cellStyle({
                        column,
                        columnIndex
                    })
                }
                return {}
            }
        },
        getCellStyle() {
            return (row, column, rowIndex, columnIndex) => {
                const cellStyle = this.cellStyle;
                if (typeof cellStyle === 'function') {
                    return cellStyle({
                        row,
                        column,
                        rowIndex,
                        columnIndex
                    })
                }
                return {}
            }
        },
    },
    data() {
        return {
            button: [],
            alipayScrollTop: 0,
            alipayScrollOldTop: 0,
            alipayFlag: false,
            bodyTableLeft: 0,
            headerTableLeft: 0,
            lastScrollLeft: 0,
            isLoadMore: false,
            headerFooterTableLeft: 0,
            leftFiexScrollTop: 0,
            bodyScrollTop: 0,
            currentDriver: null,
            currentDriver1: null,
            bodyTime: null,
            currentRowIndex: null,
            currentRow: {},
            bodyTime1: null,
            headerTime: null,
            debounceTime: null,
            operation: {},
            completedFlag: false,
            selectArr: [],
            indeterminate: false,
            checkedAll: false,
            completeLoading: false,
            aliTime: null,
        }
    },
    created() { },
    mounted() {

        // setTimeout(()=>{
        //   uni.createSelectorQuery().in(this).select(".top-header-uni").boundingClientRect( data => {
        //     console.log('data=======',data)
        //     //data  可以打印data输出看详细数据，有很多数据信息
        //     var left = data.width;//表示元素宽度
        //   }).exec();
        // },1000)
    },
    beforeDestroy() {
        this.aliTime && clearTimeout(this.aliTime)
        this.debounceTime && clearTimeout(this.debounceTime)
        this.bodyTime1 && clearTimeout(this.bodyTime1)
        this.bodyTime && clearTimeout(this.bodyTime)
        this.selectArr = []
        this.indeterminate = false
        this.checkedAll = false

    },
    methods: {
        clearSelection() {
            this.transData.forEach(item => {
                item.checked = false
            })
            this.selectArr = []
            this.indeterminate = false
            this.checkedAll = false
        },
        formatterAction(row, column, rowIndex, columnIndex) {
            if (column.formatter && typeof this.formatter === 'function') {
                return this.formatter(row, column, rowIndex, columnIndex)
            }
            return (row[column.name] == null || row[column.name] === '') ? column.emptyString : row[column.name]
        },
        permission(item, renders, index) {
            if (this.permissionBtn && typeof this.permissionBtn === 'function') {
                return this.permissionBtn(item, renders, index)
            }
            return renders
        },
        pullUpCompleteLoading(type) {
            this.isLoadMore = false
            if (type === 'ok') {
                this.completeLoading = true
            }
        },
        scrollAlipay(e) {

            if (!this.alipayScrollOldTop) {
                this.alipayScrollOldTop = e.detail.scrollTop
            }
            this.aliTime && clearTimeout(this.aliTime)
            this.aliTime = setTimeout(() => {

                if (this.alipayFlag && e.detail.scrollTop > this.alipayScrollOldTop) {
                    this.pullLoad()
                }
                this.alipayFlag = false
                this.alipayScrollOldTop = null
            }, 500)
        },
        pullLoad() {
            if (this.isShowLoadMore) {
                this.isLoadMore = true
                this.$emit('pullUpLoading')
                let that = this
                this.pullUpLoading && this.pullUpLoading.call(this.$parent.$parent, (type) => {
                    that.isLoadMore = false
                    if (type === 'ok') {
                        that.completeLoading = true
                    }
                })
            }

        },
        scrolltolower(e) {
            this.alipayFlag = true
            if (e.detail.direction === 'bottom') {
                this.pullLoad()
            }

            // this.pullUpLoading.call(this.$parent)
        },
        previewImage(item, url, current) {
            let urls = typeof url === 'string' ? [url] : url
            uni.previewImage({
                current,
                urls: urls
            })
        },
        resetHighlight() {
            this.currentRowIndex = null
            this.currentRow = {}
        },
        cellClick(row, index, column) {
            this.$emit('cellClick', row, index, column)
        },
        rowClick(row, index) {
            if (this.highlight) {
                this.currentRowIndex = index
                this.currentRow = row
                this.$emit('currentChange', row, index)
            }
            this.$emit('rowClick', row, index)
        },
        checkboxSelectedAll(e) {
            this.indeterminate = false
            if (e.checked) {
                this.selectArr = []
                this.checkedAll = true
                this.data.forEach(item => {
                    // this.$set(item,'checked',true)
                    item.checked = true
                    this.selectArr.push(item)
                })
            } else {
                this.checkedAll = false
                this.data.forEach(item => {
                    this.$set(item, 'checked', false)
                })
                this.selectArr = []
            }
            // #ifndef H5 || APP-PLUS
            this.$forceUpdate()
            // #endif
            this.$emit('toggleAllSelection', e.checked, this.selectArr)
        },
        checkboxSelected(e, item) {
            if (this.isSingle) {
                this.selectArr = []
                this.data.forEach(item => {
                    if (item.key != e.data.key) {
                        item.checked = false
                    } else {
                        item.checked = true
                    }
                })
                this.selectArr.push(this.data.find(iy => iy.checked === true))
                this.$forceUpdate()
                this.$emit('toggleRowSelection', e.checked, this.selectArr)
            } else {
                // #ifdef H5 || APP-PLUS
                this.$set(item, 'checked', e.checked)
                // #endif
                // #ifndef H5 || APP-PLUS
                this.data.forEach(item => {
                    if (item.key === e.data.key) {
                        item.checked = e.checked
                    }
                })
                // #endif
                item.checked = e.checked
                e.data.checked = e.checked
                if (e.checked) {
                    this.selectArr.push(e.data)
                } else {
                    this.selectArr = this.selectArr.filter(item => item.key !== e.data.key)
                }
                if (this.selectArr.length === this.transData.length) {
                    this.indeterminate = false
                    this.checkedAll = true
                } else {
                    this.indeterminate = true
                    this.checkedAll = false
                }
                if (!this.selectArr.length) {
                    this.checkedAll = false
                    this.indeterminate = false
                }
                // #ifndef H5 || APP-PLUS
                this.$forceUpdate()
                // #endif
                this.$emit('toggleRowSelection', e.checked, this.selectArr)
            }
        },
        itemFilter(item, ite) {
            if (ite.filters && ite.name) {
                let key = item[ite.name]
                return ite.filters[key] || ''
            }
            return item[ite.name] || ite.emptyString
        },
        // 默认字体为微软雅黑 Microsoft YaHei,字体大小为 14px
        getTextWidth(str) {
            if (str.length < 3) {
                return 40
            }
            let regx = /^[0-9]+.?[0-9]*$/
            let flexWidth = 0
            for (const char of str) {
                if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
                    // 如果是英文字符，为字符分配8个单位宽度
                    flexWidth += 10
                } else if (char >= '\u4e00' && char <= '\u9fa5') {
                    // 如果是中文字符，为字符分配15个单位宽度
                    flexWidth += 15
                } else if (regx.test(char)) {
                    flexWidth += 9
                } else {
                    // 其他种类字符，为字符分配8个单位宽度
                    flexWidth += 7
                }
            }
            return flexWidth
        },
        width(item) {
            return `${item.width ? item.width : '100'}px`
        },
        showStripe(index) {
            if (this.currentDriver) return
            if (this.stripe) {
                return (index % 2) != 0 ? 'odd' : 'even'
            } else {
                return ''
            }
        },
        //验证字符串是否是数字
        checkNumber(theObj) {
            var reg = /^[0-9]+.?[0-9]*$/;
            if (reg.test(theObj)) {
                return true;
            }
            return false;
        },
        isDate(data) {
            if (isNaN(data) && !isNaN(Date.parse(data))) {
                return true
            }
            return false
        },
        sortAction(item, index) {
            if (!item.sorter) {
                return false
            }
            this.$set(item, 'sorterMode', item.sorterMode === '_asc' ? '_desc' : '_asc')
            if (item.sorter === 'custom') {
                this.$emit('sort-change', item, item.sorterMode.replace('_', ''), index)
            } else {
                this.sortData(item)
            }
            // #ifndef H5 || APP-PLUS
            this.$forceUpdate()
            // #endif
        },
        sortData(item) {
            let key = item.name

            if (item.sorterMode === '_asc') {
                this.data.sort((a, b) => {
                    if (this.checkNumber(a[key])) {
                        return a[key] - b[key]
                    }
                    if (this.isDate(a[key])) {
                        let a1 = new Date(a[key]).getTime()
                        let b1 = new Date(b[key]).getTime()
                        return a1 - b1
                    }
                })
            } else {
                this.data.sort((a, b) => {
                    if (this.checkNumber(a[key])) {
                        return b[key] - a[key]
                    }
                    if (this.isDate(a[key])) {
                        let a1 = new Date(a[key]).getTime()
                        let b1 = new Date(b[key]).getTime()
                        return b1 - a1
                    }
                })
            }
        },
        throttle(method, delay = 60) {
            let time = null
            return (...args) => {
                if (!time) {
                    time = setTimeout(() => {
                        method(...args)
                        time = null;
                    }, delay)
                }
            }
        },
        debounce(method, delay = 1000) {
            return (...args) => {
                this.debounceTime && clearTimeout(this.debounceTime)
                this.debounceTime = setTimeout(() => {
                    method(...args)
                }, delay)
            }
        },
        handleBodyScroll(e) {
            if (this.currentDriver && this.currentDriver !== e.currentTarget.id) return
            this.currentDriver = e.currentTarget.id
            this.headerTableLeft = e.detail.scrollLeft
            this.headerFooterTableLeft = e.detail.scrollLeft
            this.leftFiexScrollTop = e.detail.scrollTop
            this.bodyTime && clearTimeout(this.bodyTime)
            this.bodyTime = setTimeout(() => {
                this.currentDriver = null
            }, 200)

        },
        leftFixedScrollAction(e) {
            if (this.currentDriver && this.currentDriver !== e.currentTarget.id) return
            this.currentDriver = e.currentTarget.id
            this.bodyScrollTop = e.detail.scrollTop
            this.bodyTime && clearTimeout(this.bodyTime)
            this.bodyTime = setTimeout(() => {
                this.currentDriver = null
            }, 200)
        },
        scrollToLeft(e) {
            if (this.currentDriver1 && this.currentDriver1 !== e.currentTarget.id) return
            this.currentDriver1 = e.currentTarget.id
            if (e.detail.direction === 'left' && this.headerTableLeft < 10) {
                this.headerTableLeft = 0
            } else if (e.detail.direction === 'top' && this.leftFiexScrollTop < 10) {
                this.leftFiexScrollTop = 0
            }
            this.bodyTime && clearTimeout(this.bodyTime)
            this.bodyTime = setTimeout(() => {
                this.currentDriver1 = null
            }, 200)
        },
        scrollToFixedLeft(e) {
            if (this.currentDriver1 && this.currentDriver1 !== e.currentTarget.id) return
            this.currentDriver1 = e.currentTarget.id
            if (e.detail.direction === 'top' && this.bodyScrollTop < 10) {
                this.bodyScrollTop = 0
            }
            this.bodyTime && clearTimeout(this.bodyTime)
            this.bodyTime = setTimeout(() => {
                this.currentDriver1 = null
            }, 200)
        },
        handleTableScrollLeft(e, type) {
            if (this.currentDriver && this.currentDriver !== e.currentTarget.id) return
            this.currentDriver = e.currentTarget.id
            this.bodyTableLeft = e.detail.scrollLeft
            this.headerFooterTableLeft = e.detail.scrollLeft
            this.bodyTime && clearTimeout(this.bodyTime)
            this.bodyTime = setTimeout(() => {
                this.currentDriver = null
            }, 200)
        },
        handleFooterTableScrollLeft(e) {
            if (this.currentDriver && this.currentDriver !== e.currentTarget.id) return
            this.currentDriver = e.currentTarget.id
            this.bodyTableLeft = e.detail.scrollLeft
            this.headerTableLeft = e.detail.scrollLeft
            this.bodyTime && clearTimeout(this.bodyTime)
            this.bodyTime = setTimeout(() => {
                this.currentDriver = null
            }, 200)
        }
    }
}
</script>
<style lang="scss">
.zb-table-fixed-left {
  /*去除左边滚动条 */
  scroll-view ::-webkit-scrollbar {
    display: none !important;
    width: 0 !important;
    height: 0 !important;
    -webkit-appearance: none;
    background: transparent;
  }
}

.zb-table-header {
  ///*去除头部滚动条 */
  scroll-view ::-webkit-scrollbar {
    display: none !important;
    width: 0 !important;
    height: 0 !important;
    -webkit-appearance: none;
    background: transparent;
  }
}
</style>
<style lang="scss" scoped>
.sorter-table {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);

  .sorter-table-icon {
    width: 0;
    height: 0;
    color: #dcdcdc;
    border-right: 4px solid transparent;
    border-left: 4px solid transparent;
  }

  .sorter-table-icon:first-child {
    border-bottom: 5px solid currentColor;
  }

  .sorter-table-icon:last-child {
    margin-top: 1.5px;
    border-top: 5px solid currentColor;
  }

  .sorting_desc {
    color: #2979ff;
  }

  .sorting_asc {
    color: #2979ff;
  }
}

.checkbox-item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.no-data {
  width: 100%;
  height: 80rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  border-bottom: 1px solid #e8e8e8;
}

.item-th {
  position: relative;
  flex-shrink: 0;
  width: 100px;
  overflow-wrap: break-word;
  border-bottom: 1px solid #e8e8e8;
  transition: background 0.3s;
  padding-right: 20px;
  word-break: keep-all;
  /* 不换行 */
  white-space: nowrap;
  /* 不换行 */
  overflow: hidden;
  /* 内容超出宽度时隐藏超出部分的内容 */
  text-overflow: ellipsis;
  /* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/
  overflow-wrap: break-word;
}

.zb-table {
  height: 100%;
  overflow: hidden;
  width: 100%;
  display: flex;
  flex-direction: column;
  font-size: 12px;
  position: relative;

  .zb-table-content {
    //height: 100%;
    //flex: 1;
    position: relative;
    overflow: hidden;
  }

  .zb-table-fixed {
    min-width: 100%;
  }

  .zb-table-body {
    position: relative;
    background: #fff;
    transition: opacity 0.3s;
  }

  .item-tr {
    display: flex;
    //height: 41px;
  }

  .item-td {
    flex-shrink: 0;
    width: 100px;
    padding-left: 8px;
    height: 40px;
    line-height: 40px;
    padding-right: 20px;
    box-sizing: border-box;
    word-break: keep-all;
    /* 不换行 */
    white-space: nowrap;
    /* 不换行 */
    overflow: hidden;
    /* 内容超出宽度时隐藏超出部分的内容 */
    text-overflow: ellipsis;
    /* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/
    overflow-wrap: break-word;
    border-bottom: 1px solid #e8e8e8;
    //transition: background 0.3s;
  }

  .zb-table-fixed-left .zb-table-header {
    overflow-y: hidden;
  }

  .zb-table-header {
    overflow: hidden;
    background: #fafafa;

    .item-th {
      padding-left: 8px;
      line-height: 39px;
      height: 40px;
      //display: flex;
      //align-items: center;
      box-sizing: border-box;
    }
  }

  .zb-table-fixed-left .zb-table-fixed {
    background: #fff;
  }

  .zb-table-fixed-right .zb-table-fixed {
    background: #fff;
  }

  .zb-table-body-inner {
    height: 100%;
    // overflow: scroll;
  }

  .zb-table-fixed-left {
    position: absolute;
    top: 0;
    z-index: 1;
    overflow: hidden;
    border-radius: 0;
    height: 100%;
    //transition: box-shadow 0.3s ease;
  }

  .odd {
    background-color: rgba(249, 249, 249, 0.6);
    //height: 100%;
    width: 100%;
  }

  .even {
    background-color: white;
    //height: 100%;
    width: 100%;
  }
}

.scroll-left-fixed {
  .zb-table-fixed-left {
    left: 0;
    box-shadow: 6px 0 6px -4px #ccc;
  }
}

.zb-table-applet {
  height: 100%;
  //overflow: hidden;
  width: 100%;
  position: relative;
  display: flex;
  flex-direction: column;
  font-size: 12px;

  .zb-table-content {
    //height: 100%;
    flex: 1;
    overflow: hidden;
    position: relative;
  }

  .zb-table-fixed {
    min-width: 100%;
    width: fit-content;
  }

  .zb-table-body {
    position: relative;
    background: #fff;
    transition: opacity 0.3s;
  }

  .item-tr {
    display: flex;
    //height: 41px;
  }

  .item-td {
    flex-shrink: 0;
    width: 100px;
    padding-left: 8px;
    height: 40px;
    line-height: 40px;
    padding-right: 20px;
    box-sizing: border-box;
    word-break: keep-all;
    /* 不换行 */
    white-space: nowrap;
    /* 不换行 */
    overflow: hidden;
    /* 内容超出宽度时隐藏超出部分的内容 */
    text-overflow: ellipsis;
    /* 当对象内文本溢出时显示省略标记(...) ；需与overflow:hidden;一起使用。*/
    overflow-wrap: break-word;
    border-bottom: 1px solid #e8e8e8;
    //transition: background 0.3s;
  }

  .zb-table-header {
    //overflow: hidden;
    position: sticky;
    top: 0;
    z-index: 2;

    //width: fit-content;
    .item-th {
      padding-left: 8px;
      line-height: 39px;
      height: 40px;
      box-sizing: border-box;
      background: #fafafa;
    }

    .zb-stick-side {
      position: sticky;
      top: 0;
      left: 0;
      z-index: 2;
      //border-right: solid 1rpx #dbdbdb;
      box-sizing: border-box;
      background: #fafafa;
      //box-shadow: 6px 0 6px -4px #ccc;
    }
  }

  .zb-table-fixed-left .zb-table-fixed {
    background: #fff;
  }

  .zb-table-fixed-right .zb-table-fixed {
    background: #fff;
  }

  .zb-table-fixed-header .zb-table-body-inner {
    height: 100%;
    // overflow: scroll;
  }

  .zb-table-fixed-left {
    position: absolute;
    top: 0;
    z-index: 1;
    overflow: hidden;
    border-radius: 0;
    height: 100%;
    //transition: box-shadow 0.3s ease;
  }

  .scroll-left-fixed {
    .zb-table-fixed-left {
      left: 0;
      box-shadow: 6px 0 6px -4px #ccc;
    }
  }

  .odd {
    background-color: rgba(249, 249, 249, 0.6);
    //height: 100%;
    width: 100%;
  }

  .even {
    background-color: white;
    //height: 100%;
    width: 100%;
  }

  .zb-table-tbody {
    .zb-stick-side {
      position: sticky;
      left: 0;
      z-index: 1;
      box-sizing: border-box;
      background: white;
      //box-shadow: 6px 0 6px -2px #ccc;
    }

    .odd {
      background: #f9f9f9;
      //height: 100%;
      width: 100%;
    }

    .even {
      background: white;
      //height: 100%;
      width: 100%;
    }
  }

  .current-row {
    .item-td {
      background-color: #ecf5ff;
    }
  }
}

.current-row {
  .item-td {
    background-color: #ecf5ff;
  }
}

.zb-table-header {
  height: 40px;
}

.scrollPosition {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  background: red;
  z-index: 999;
}
</style>